home *** CD-ROM | disk | FTP | other *** search
-
- #include <Files.h>
- #include <Folders.h>
- #include <Memory.h>
- #include <TextUtils.h>
-
- #define kMaxVolsChecked 10
-
- static void SizeTrashCan (StringPtr sizeString);
- static long SizeDirectory (short vRefNum, long dirID);
-
- pascal void
- TrashHack (StringPtr sizeString)
- {
- if (EqualString (sizeString, "\pTrash", false, false))
- {
- SizeTrashCan (sizeString);
- }
- }
-
- void
- SizeTrashCan (StringPtr sizeString)
- {
- short vRefNum;
- short trashVRefNum;
- short i;
- long trashDirID;
- long trashSize;
- Str31 buffer;
- HVolumeParam vpb;
-
- // initialise the trash size
- trashSize = 0;
-
- // initialise (ignored) volume name
- buffer [0] = 0;
-
- // for each mounted volume
- for (i = 0; i < kMaxVolsChecked; i++)
- {
- // get vRefNum of nth mounted volume
- vpb.ioCompletion = nil;
- vpb.ioVolIndex = i + 1;
- vpb.ioNamePtr = buffer;
-
- // get vol info
- if (PBHGetVInfo ((HParmBlkPtr) &vpb, false) == noErr)
- {
- // check volume is online
- if (vpb.ioVDRefNum < 0)
- {
- // extract volume refnum
- vRefNum = vpb.ioVRefNum;
-
- // find the trashcan
- if (FindFolder (vRefNum, kTrashFolderType, kDontCreateFolder,
- &trashVRefNum, &trashDirID) == noErr)
- {
- // we have a trash can!
-
- // increment the total
- trashSize += SizeDirectory (trashVRefNum, trashDirID);
- }
- else
- {
- // can't FindFolder on trashcan
- }
- }
- else
- {
- // volume is offline
- }
- }
- else
- {
- // can't PBHGetVInfo
- }
- }
-
- if (trashSize)
- {
- // over a megabyte?
- if (trashSize > (1024L * 1024L))
- {
- // give size in megabytes
- NumToString (trashSize / (1024L * 1024L), buffer);
- buffer [++buffer [0]] = 'M';
- }
- else
- {
- // give size in kilobytes
- NumToString (trashSize / 1024L, buffer);
- buffer [++buffer [0]] = 'K';
- }
-
- // check length is •exactly• right
- if (buffer [0] <= 5)
- {
- while (buffer [0] < 5)
- {
- buffer [++buffer [0]] = ' ';
- }
-
- BlockMoveData (buffer, sizeString, 6);
- }
- }
- else
- {
- // otherwise the string is a misleading “0K”
- BlockMoveData ("\pzeroK", sizeString, 6);
- }
- }
-
- // returns the combined size of the entries within the specified directory
- // calls itself if it finds a directory beneath the specified directory
- // “topLevel” parameter specifies whether this is the first iteration
- // used as a check to see whether the trashcan has been modified since last call
- static long
- SizeDirectory (short vRefNum, long dirID)
- {
- OSErr errCode;
- CInfoPBRec pb;
- Str31 nameBuffer;
- long totalSize = 0;
- unsigned short numItems;
- unsigned short i;
-
- // make up a GetCatInfo paramblock
- // to get info on the directory whose ID we are passed
- pb.dirInfo.ioCompletion = nil;
- pb.dirInfo.ioNamePtr = nameBuffer;
- pb.dirInfo.ioVRefNum = vRefNum;
- pb.dirInfo.ioFDirIndex = -1;
- pb.dirInfo.ioDrDirID = dirID;
-
- // get cat info!
- errCode = PBGetCatInfo (&pb, false);
-
- // check error code
- if (errCode != noErr)
- {
- // oops - can't get info for this directory - return zero size
- return 0;
- }
-
- // find out how many entries we have in the directory
- numItems = pb.dirInfo.ioDrNmFls;
-
- // loop thru each - the index starts at 1, remember
- for (i = 1; i <= numItems; i++)
- {
- // configure the paramblock appropriately
- // note have to reinitialise the dirID field every time
- pb.dirInfo.ioFDirIndex = i;
- pb.dirInfo.ioDrDirID = dirID;
-
- // get the stuff about the file/dir
- errCode = PBGetCatInfo (&pb, false);
-
- // check error code
- if (errCode != noErr)
- {
- // oops - can't get info on this entry
- // leave well alone
- continue;
- }
-
- // if it's a directory
- if (pb.dirInfo.ioFlAttrib & ioDirMask)
- {
- // SUBDIRECTORY
-
- // call myself to find its size and add that to the total
- totalSize += SizeDirectory (vRefNum, pb.dirInfo.ioDrDirID);
- }
- else
- {
- // FILE
-
- // take the •physical• sizes of the data and resource forks
- totalSize += pb.hFileInfo.ioFlPyLen + pb.hFileInfo.ioFlRPyLen;
- }
- }
-
- return totalSize;
- }
-